<?php

namespace App\Http\Controllers\Manager;

use App\Events\ManagerMoneyChangeEvent;
use App\Http\Controllers\Controller;
use App\Helper;
use App\Http\Requests\ServerStoreRequest;
use App\Http\Requests\ServerUpdateRequest;
use App\Models\Goods;
use App\Models\GoodsCategory;
use App\Models\Item;
use App\Models\Player;
use App\Models\PlayerMoneyLog;
use App\Models\Server;
use DateInterval;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ServerController extends Controller
{

    public $prefix='manager.server';
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $all=$request->get('all');
        $user=Auth::user();
        $servers=null;
        if ($all==1 && $user->is_admin==1){
            $servers=Server::all();
        }else{
            $servers=$user->servers;
        }

        return view($this->prefix.'.list',compact('servers'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view($this->prefix.'.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ServerStoreRequest $request)
    {
        $data=$request->all();
        $data['soap_acc']=strtoupper($data['soap_acc']);
        $item=new Server();
        $item->fill($data);
        $item->type='1';
        $item->version='1';
        $item->user_id=Auth::id();
        $item->endTime=Carbon::now()->addDays(config('conf.default.newServerFreeDays'));
        $item->ratio=config('conf.default.serverRatio');
        $item->state=config('conf.default.serverState');
        $item->save();
        return redirect('manager/server');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $server =Server::find($id);
//        dd($server);
        $res='';
        $err='';
        $server->ServerInfo($res,$err);

//        $COMMAND=".server info";
//        $soapInfo = [
//            'soap_uri' => 'urn:AC',
//            'soap_host' => $server->soap_host,
//            'soap_port' => $server->soap_port,
//            'soap_acc' => $server->soap_acc,
//            'soap_pwd' => $server->soap_pwd
//        ];
//
//        dd($soapInfo);
//
//
//        try {
//            $conn = new SoapClient(NULL, array(
//                'location' => 'http://' . $soapInfo['soap_host'] . ':' . $soapInfo['soap_port'] . '/',
//                'uri' => $soapInfo['soap_uri'],
//                'style' => SOAP_RPC,
//                'login' => $soapInfo['soap_acc'],
//                'password' => $soapInfo['soap_pwd']
//            ));
//            $result = $conn->executeCommand(new SoapParam($COMMAND, 'command'));
//            unset($conn);
//        } catch (Exception $e) {
//            $err = "Have error on soap: ".$e->getMessage();
//
//            if (strpos($e, 'There is no such command') !== false) {
//                $err = 'There is no such command!';
//            }
//        }


        return view($this->prefix.'.info',compact('server','err','res'));


//        dd($server);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $server =Server::find($id);
        return view($this->prefix.'.edit',compact('server'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(ServerUpdateRequest $request, $id)
    {
        $data=$request->all();
        $data['soap_acc']=strtoupper($data['soap_acc']);
        $item=Server::find($id);
        //dd($request->all());
        $item->fill($data);
        $item->save();
        return redirect('manager/server');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $item=Server::find($id);
        Player::where('server_id',$item->id)->delete();
        PlayerMoneyLog::where('server_id',$item->id)->delete();
        $item->server_host.='_del';
        $item->domain.='_del';
        $item->save();
        $item->delete();
        return redirect('manager/server')->with('msg','删除成功');
    }

    public function command(Request $request,$id){
        $server=$this->CheckServer($id);
        $command=$request->get('command');
        $res='';
        $err='';
        $server->RunCommand('.'.$command,$res,$err);

        if ($err){
            return back()->with('msg','<span class="badge badge-danger">错误</span> '.$err);
        }else{
            return back()->with('msg','<span class="badge badge-success">成功</span> '.$res);
        }
    }


    public function mall($id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');
        return view($this->prefix.'.mall',['server'=>$server]);
    }

    public function status($id){
        $server=$this->CheckServer($id);
        return view($this->prefix.'.status',['server'=>$server]);
    }
    public function statusBt($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->statusBt()]);
    }
    public function statusSSH($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->statusSSH()]);
    }
    public function statusDB($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->statusDB()]);
    }
    public function statusSOAP($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->statusSOAP()]);
    }
    public function resetPwd($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->resetPwd()]);
    }

    public function getVersion($id){
        $server=$this->CheckServer($id);
        $version=0;
        try {
            $version=$server->getVersion();
            return JsonResponse::create(['err'=>0,'data'=>$version]);
        }catch (\Exception $e){
            return JsonResponse::create(['err'=>0,'data'=>$version]);
        }
    }
    public function getMotd($id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_auth');

        try {
            $exists=DB::connection('mysql_world')->table('motd')->exists();
            $list=DB::connection('mysql_world')->table('motd')->get();
            return JsonResponse::create(['err'=>0,'data'=>$list]);
        }catch (\Exception $e){
            return JsonResponse::create(['err'=>0,'data'=>[]]);
        }
    }
    public function setMotd(Request $request,$id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_auth');
        $res=DB::connection('mysql_world')->table('motd')
            ->where('realmid',-1)->update(['text'=>$request->get('text')]);
        return JsonResponse::create(['err'=>0,'data'=>$res]);
    }

    public function goodsSearch(Request $request,$id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');
        $key = $request->get('key');

        if (!$key){
            return JsonResponse::create(['err'=>1,'msg'=>'请输入查询关键字']);
        }
//        $item=new Item();
        $list=Item::search($key);

        foreach ($list as $item){
            $item->item;
        }
        return JsonResponse::create(['err'=>0,'data'=>$list->all()]);
    }

    public function  goodsAdd(Request $request,$id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');

        $item_id=$request->get('entry');
        $count=Goods::where('server_id',$id)->where('item_id',$item_id)->count();
        if ($count>0){
            return JsonResponse::create(['err'=>1,'msg'=>'此物品已经在出售中']);
        }

        $count_all=Goods::where('server_id',$id)->count();
        if ($count_all>=config('conf.goodsCountMax')){
            return JsonResponse::create(['err'=>1,'msg'=>'出售商品数量已满']);
        }

        $goods=new Goods();
        $goods->fill($request->all());
        $goods->item_id=$item_id;
        $goods->server_id=$id;
        $goods->save();
        $goods->item;
        return JsonResponse::create(['err'=>0,'data'=>$goods]);

    }

    public function  goodsUpdate(Request $request,$id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');


        $item=Goods::find($request->get('id'));
        if (!$item){
            return JsonResponse::create(['err'=>1,'msg'=>'无效的商品']);
        }else{
            $item->price=$request->get('price');
            $item->order=$request->get('order');
            $item->cat_id=$request->get('cat_id');
            $item->save();
            return JsonResponse::create(['err'=>0,'data'=>$item]);
        }
    }
    public function  goodsRemove(Request $request,$id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');

        $item=Goods::find($request->get('id'));
        if (!$item){
            return JsonResponse::create(['err'=>1,'msg'=>'无效的商品']);
        }else{
            $item->delete();
            return JsonResponse::create(['err'=>0]);
        }
    }

    public function goodsList($id){
        $server=$this->CheckServer($id);
        Helper::setDataBaseConf('mysql_world',$server,'acore_world');

        $list=$server->goods;
        foreach ($list as $item){
            $item->item;
        }
        return JsonResponse::create(['err'=>0,'data'=>$list]);
    }
    public function goodsCatList($id){
        $server=$this->CheckServer($id);
//        Helper::setDataBaseConf('mysql_world',$server,'acore_world');

        $list=$server->goodsCategory;
//        foreach ($list as $item){
//            $item->item;
//        }
        return JsonResponse::create(['err'=>0,'data'=>$list]);
    }
    public function goodsCatAdd(Request $request,$id){
//        $server=$this->CheckServer($id);
        $title=$request->get('title');
        $item=new GoodsCategory();
        $item->server_id=$id;
        $item->title=$title;
        $item->save();

        return JsonResponse::create(['err'=>0,'data'=>$item]);
    }
    public function goodsCatUpdate($id){

    }
    public function goodsCatDel(Request $request,$id){
        $id=$request->get('id');
        $item=GoodsCategory::find($id);
        $item->delete();
        return JsonResponse::create(['err'=>0,'data'=>$item]);
    }

    public function config(Request $request,$id){
        $server=$this->CheckServer($id);
//        dd($server->ext);
        if (!$server->ext) $server->ext='{"payforlevel":"0","payforlevelMax":"60","moneyForPerLevel":"10","timetomoney":"0","timetoscore":"0","timetomoneyRatio":"10","bgUrl":null,"loginUrl":null}';
        return view($this->prefix.'.config',['server'=>$server]);
    }

    public function configBase($id){
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>$server->ext]);
    }

    public function configBaseUpdate(Request $request,$id){
        $server=$this->CheckServer($id);
//        dd($request->get('business'));
        $data=$request->get('data');
        $server->state= $request->get('state');
        $server->business= $request->get('business');
        $server->template= $request->get('tmp');
        $server->info= $request->get('serverInfo');
        $server->qq_group= $request->get('serverQQGroup');
        $server->ext= json_encode($data);
        $server->save();

        return JsonResponse::create(['err'=>0,'data'=>$data]);
    }

    public function getWorldServerConf(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        $data = $server->getWorldServerConf();
        return JsonResponse::create(['err'=>0,'data'=>$data,'info'=>$server->BtApi->getInfo()]);
    }
    public function runGMCommand(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        $command=$request->get('command');
        if ($command[0]!=='.') $command='.'.$command;
        $res='';
        $err='';
        $server->RunCommand($command,$res,$err);

        if ($err){
            return JsonResponse::create(['err'=>0,'data'=>0,'return'=>['res'=>$res,'err'=>$err]]);
        }else{
            return JsonResponse::create(['err'=>0,'data'=>1,'return'=>['res'=>$res,'err'=>$err]]);
        }
    }

    public function launcherOn(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        $res=$server->CreateLauncher();
        return JsonResponse::create(['err'=>0,'data'=>1,'return'=>$res]);
    }

    public function getLauncherConfig(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        return JsonResponse::create(['err'=>0,'data'=>1,'return'=>$server->launcherConfig]);
    }
    public function launcherConfigSave(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        $launcherConfig=$request->get('launcherConfig');
        $lc=$server->launcherConfig;
        $lc->news=$launcherConfig['news']??'';
        $lc->links=$launcherConfig['links']??'';
        $lc->patchlist=$launcherConfig['patchlist']??'';
        $lc->patchtodel=$launcherConfig['patchtodel']??'';
        $lc->save();

        return JsonResponse::create(['err'=>0,'data'=>1,'return'=>$lc]);
    }

    public function gm($id){
        $server=$this->CheckServer($id);
        return view($this->prefix.'.gm',['server'=>$server]);
    }

    public function saveWorldServerConf(Request $request){
        $id=$request->get('id');
        $server=$this->CheckServer($id);
        $dataStr=$request->get('data');
        $server->world_server_conf=$dataStr;
        $server->save();
        $data=json_decode($dataStr);

        $WorldServerConfString = <<<___


[worldserver]

LogLevel = 2
CloseIdleConnections = 0

SOAP.Enabled = 1
SOAP.IP = "0.0.0.0"
SOAP.Port = 7878


# 自定义属性

___;

        if ($server->type===2)
            $WorldServerConfString = <<<___
[worldserver]
SOAP.Enabled = 1
SOAP.IP = "0.0.0.0"
# 自定义属性

___;

        foreach ($data as $k=>$v){
            if ($k!='customConfig'){
                if ($v->type=='string'){
                    $WorldServerConfString .= <<<___
$k = "$v->value"

___;
                }else{
                    $WorldServerConfString .= <<<___
$k = $v->value

___;
                }
            }else{
//                $custom = explode('\n',$v->value);
//                foreach ($custom as $item){
//                    $WorldServerConfString .= <<<___
//$item
//
//___;
//                }
                $WorldServerConfString .=$v->value;

            }
        }

        $res = $server->saveWorldServerConf($WorldServerConfString);
        return JsonResponse::create(['err'=>0, 'res'=>$res, 'data'=>'']);
    }

    public function lua($id){
        $server=$this->CheckServer($id);
        return view($this->prefix.'.lua',compact('server'));
    }
    public function luaList($id){
        $server=$this->CheckServer($id);
        $files=$server->luaList();
        return JsonResponse::create(['err'=>0, 'res'=>$files, 'data'=>'']);
    }
    public function luaAdd(Request $request,$id){
        $server=$this->CheckServer($id);
        $name=$request->get('name');
        $script=$request->get('script');
        $res1=$server->createLuaFile($name.'.lua');
        $res2=$server->saveLuaFile($name.'.lua',$script);
        return JsonResponse::create(['err'=>0, 'res'=>[
            'create'=>$res1,
            'save'=>$res2,
        ]]);
    }

    public function luaDel(Request $request,$id){
        $server=$this->CheckServer($id);
        $name=$request->get('name');
        $type=$request->get('type');
        $res=$server->delLuaFile($name.'.'.$type);
        return JsonResponse::create(['err'=>0, 'res'=>$res]);
    }

    public function luaStatus(Request $request,$id){
        $server=$this->CheckServer($id);
        $name=$request->get('name');
        $typeNew=$request->get('type');
        $typeOld=($typeNew=='lua'?'lua-':'lua');
        $res=$server->changeLuaStatus($name.'.'.$typeOld,$name.'.'.$typeNew);

        return JsonResponse::create(['err'=>0, 'res'=>$res]);
    }

    public function luaRename(Request $request,$id){
        $server=$this->CheckServer($id);
        $name_old=$request->get('name_old');
        $name=$request->get('name');
        $type=$request->get('type');
        $res=$server->renameLuaFile($name_old.'.'.$type,$name.'.'.$type);
        return JsonResponse::create(['err'=>0, 'res'=>$res]);
    }

    public function luaScript(Request $request,$id){
        $server=$this->CheckServer($id);
        $name=$request->get('name');
        $type=$request->get('type');
        $res=$server->getLuaScript($name.'.'.$type);
        return JsonResponse::create(['err'=>0, 'res'=>$res]);
    }
    public function luaUpdate(Request $request,$id){
        $server=$this->CheckServer($id);
        $name=$request->get('name');
        $type=$request->get('type');
        $data=$request->get('script');
        $res=$server->setLuaScript($name.'.'.$type,$data);
        return JsonResponse::create(['err'=>0, 'res'=>$res]);
    }
    public function luaReload($id){
        $server=$this->CheckServer($id);
        $res='';
        $err='';
        $server->ReloadEluna($res,$err);
        if ($err) {
            return JsonResponse::create(['err'=>1,'msg'=>$err]);
        }else{
            return JsonResponse::create(['err'=>0,'data'=>$res]);
        }
    }

    public function serverList(Request $request){
        $all=$request->get('all');
        $ip=$request->get('ip');
        $page=$request->get('page');
        $size=$request->get('size');
        $user=Auth::user();
        $servers=null;
        if ($all>0 && $user->is_admin==1){
            if ($all==1){
                $servers=Server::orderBy('id','desc');
            }elseif ($all=2){
                $servers=Server::where('endTime','>',Carbon::now()->add(5,'day'))->orderBy('id','desc');
            }
//            $servers=Server::select(['id','name','domain','server_host','endTime'])->orderBy('id','desc')->get();
        }else{
//            $servers=$user->servers;
            $servers=Server::where('user_id',$user->id)->orderBy('id','desc');
        }

        if ($ip){
            $servers=$servers->where('db_host',$ip);
        }

        $servers=$servers->paginate($size);

        return [
            'err'=>0,
            'data'=>$servers
        ];
    }

    public function serverRenew(Request $request){
        $id=$request->get('id');
        $m=$request->get('m');

        $server=$this->CheckServer($id);
        $user=Auth::user();

        $score=$m*config('conf.serverPrice');
        if ($score > $user->remain_money) {
            return ['err'=>1,'msg'=>'积分不足'];
        }
        $user->remain_money -= $score;
        $user->save();

        $baseDate=now(); //当前时间上添加
        if ($server->enable){
            $baseDate=date_create($server->endTime); //原有时间上添加
        }

        $di=DateInterval::createFromDateString(($m>=10?12:$m).' months');

        $newDate=date_add($baseDate,$di);
        $server->endTime=$newDate->format('Y-m-d H:i:s');
        $server->save();
        event(new ManagerMoneyChangeEvent($user->id,$server->id,0,1,2,$score,0,$user->remain_money,'服务续费'));
        return ['err'=>0];
    }

    public function serverExchangeTime(Request $request){
        $id1=$request->get('id1');
        $id2=$request->get('id2');

        if ($id1===$id2){
            return ['err'=>1,'msg'=>'错误的参数'];
        }
        $server1=$this->CheckServer($id1);
        if ($server1->enableDays<5){
            return ['err'=>1,'msg'=>'错误的参数'];
        }
        $server2=$this->CheckServer($id2);
        $id=Auth::id();
        if ($server1->user_id!=$id||$server2->user_id!=$id){
            return ['err'=>1,'msg'=>'错误的参数'];
        }
        $enditem=$server1->endTime;
        $server1->endTime=$server2->endTime;
        $server2->endTime=$enditem;
        $server1->save();
        $server2->save();
        return ['err'=>0];
    }


}
